package com.catazy.wanandroid.common_base.glide

import com.catazy.wanandroid.common_base.ext.logI
import okhttp3.MediaType
import okhttp3.ResponseBody
import okio.Buffer
import okio.BufferedSource
import okio.ForwardingSource
import okio.Source
import okio.buffer
import java.io.IOException

/**
 * 作者: Tao
 * 日期: 2024/4/10
 * 时间: 11:40
 * 描述: 下载进度响应体
 */
class ProgressResponseBody(url: String, responseBody: ResponseBody) : ResponseBody() {

    private var bufferedSource: BufferedSource? = null
    private var responseBody: ResponseBody? = null
    private var listener: ProgressListener? = null

    init {
        this.responseBody = responseBody
        listener = ProgressInterceptor.getListener(url)
    }

    override fun contentLength(): Long {
        return responseBody?.contentLength() ?: 0
    }

    override fun contentType(): MediaType? {
        return responseBody?.contentType()
    }

    override fun source(): BufferedSource {
        if (bufferedSource == null) {
            bufferedSource = ProgressSource(responseBody!!.source()).buffer()
        }
        return bufferedSource!!
    }


    inner class ProgressSource(source: Source) :
        ForwardingSource(source) {

        private var totalBytesRead: Long = 0
        private var currentProgress = 0

        @Throws(IOException::class)
        override fun read(sink: Buffer, byteCount: Long): Long {
            val bytesRead = super.read(sink, byteCount)
            val fullLength: Long = responseBody?.contentLength() ?: 0
            if (bytesRead == -1L) {
                totalBytesRead = fullLength
            } else {
                totalBytesRead += bytesRead
            }
            val progress = (100f * totalBytesRead / fullLength).toInt()
            logI("ProgressResponseBody", "download progress is $progress")
            if (progress != currentProgress) {
                listener?.onProgress(progress)
            }
            if (listener != null && totalBytesRead == fullLength) {
                listener = null
            }
            currentProgress = progress
            return bytesRead
        }
    }

}